home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xhearts
/
hearts.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-09
|
6KB
|
349 lines
/*
* hearts - human interface to hearts program
*
* All smarts are in heartsd, which is invoked by initial caller of hearts.
*
* Private messages, last-play, auto-play added by:
* Mike Yang of Silicon Graphics (mikey@sgi.com)
*
* By Bob Ankeney or Generic Computer Products
* Bug reports to:
* ...!tektronix!reed!bob
*
*
* Commands to hearts client (r = rank, s = suit):
*
* Ars Add card to hand.
* Rrs Remove card from hand.
* En Erase window n.
* G Get a card.
* Pnrs<name> Play card from player n, whose name is <name>.
* Snpptt<name> Score points (pp) and total points (tt) for player n.
* Mn<text> Message <text> is placed in window n.
* X Go away.
* Z Game over, socket closing.
*
* Messages from client:
*
* Prs Pass/Play card from hand.
* M<text> Send message <text> to all players.
*
*/
#include <sys/errno.h>
#include "misc.h"
#include "defs.h"
#include "local.h"
#include "client.h"
#ifdef SYSV
#include <sys/termio.h>
#endif
int dist_socket, dealer_socket;
char game_over, first_game;
char host[256];
char *snames[] = {
"",
"clubs",
"diamonds",
"hearts",
"spades"
},
rnames[] = " 23456789TJQKA";
get_going()
{
int dealer_port;
char *name, *getenv();
/*
* Connect to distributor. If not available, start it.
*/
if ((dist_socket = connect_to(host, PORT)) == 0) {
start_distributor();
if ((dist_socket = connect_to(host, PORT)) == 0)
death("Can't invoke distributor!");
}
/*
* Get dealer port and connect to it.
* If port returned == 0, restart game with old dealer.
*/
if (dealer_port = select_game()) {
if (!first_game) {
(void) close(dealer_socket);
close_socket(dealer_socket);
}
if ((dealer_socket = connect_to(host, dealer_port)) == 0)
death("Can't connect to dealer!\n");
if ((name = getenv("HEARTS")) == NULL) /* get user name */
if ((name = getenv("NAME")) == NULL)
name = getenv("USER");
init_socket();
write_socket(dealer_socket, name); /* tell dealer */
}
start_game();
}
do_command(buf)
char *buf;
{
char rch, sch;
int player, suit, pts, total_pts, window_num;
switch (buf[0]) {
case 'A' : /* Add card to hand */
enter_card(get_rank(buf[1]), get_suit(buf[2]));
break;
case 'R' : /* Remove card from hand */
remove_card(get_rank(buf[1]), get_suit(buf[2]));
break;
case 'E' : /* Erase window */
erase_window(buf[1] - '0');
break;
case 'G' : /* Get card */
read_card();
break;
case 'P' : /* Play card from player */
(void) sscanf(buf+1, "%1d %c %c", &player, &rch, &sch);
play_card(player, rch, sch, buf+4);
break;
case 'S' : /* Score points for player */
(void) sscanf(buf+1, "%1d %3d %3d", &player, &pts, &total_pts);
score_points(player, pts, total_pts, buf+8);
break;
case 'M' : /* Print message in window */
display_message(buf[1] - '0', buf+2);
break;
case 'X' : /* Game over */
game_is_over();
game_over = TRUE;
first_game = FALSE;
break;
case 'Z' : /* Game over, socket closing */
game_is_over();
game_over = TRUE;
first_game = TRUE;
(void) close(dealer_socket);
close_socket(dealer_socket);
}
}
/*
* Filter out nasties from message in buffer
*/
mikey_strcmp(s,t)
char s[], t[];
{
int i;
i = 0;
while ((s[i] == t[i]) || (s[i] >= 'A' && s[i] <= 'Z' &&
(s[i] - 'A' + 'a') == t[i]))
if (t[i++] == '\0')
return(TRUE);
return((t[i] == '\0'));
}
block(buf, what)
char *buf, *what;
{
int i;
for (i=0;i<=strlen(what);i++)
*buf++ = *what++;
}
mikey_filter(buf)
char *buf;
{
int i;
for (i=1;i<strlen(buf);i++) {
if (mikey_strcmp(buf+i,"asshole"))
block(buf+i,"a--hole");
if (mikey_strcmp(buf+i,"tit"))
block(buf+i,"t-t");
if (mikey_strcmp(buf+i,"shit"))
block(buf+i,"s--t");
if (mikey_strcmp(buf+i,"damn"))
block(buf+i,"d--n");
if (mikey_strcmp(buf+i,"fuck"))
block(buf+i,"f--k");
}
}
/**********************************************************************/
do_socket()
{
char buf[64];
if (!read_socket(dealer_socket, buf))
death("Dealer died!!");
do_command(buf);
}
send_message(msg)
char *msg;
{
char buf[64];
strcpy(buf, "M");
if (strlen(msg) <= 62) {
strcat(buf, msg);
} else {
strncat(buf, msg, 62);
}
mikey_filter(buf);
write_socket(dealer_socket, buf);
}
send_private_message(who, msg)
int who;
char *msg;
{
char buf[64];
sprintf(buf, ";%d", who);
if (strlen(msg) <= 61) {
strcat(buf, msg);
} else {
strncat(buf, msg, 61);
}
mikey_filter(buf);
write_socket(dealer_socket, buf);
}
toggle_private_messages()
{
char buf[2];
buf[0] = '~';
buf[1] = '\0';
write_socket(dealer_socket, buf);
}
send_card(rank, suit)
int rank, suit;
{
char buf[64];
sprintf(buf, "P%c%c", rank, suit);
write_socket(dealer_socket, buf);
}
send_auto()
{
char buf[64];
sprintf(buf, "P?%c", HEARTS);
write_socket(dealer_socket, buf);
}
close_windows()
{
(void) signal(SIGINT, SIG_IGN);
terminate();
}
death(buf)
char *buf;
{
close_windows();
printf("%s\n", buf);
exit(1);
}
wimp_out()
{
close_windows();
exit(0);
}
get_rank(rch)
int rch;
{
int i;
for (i = 1; i <= MAX_RANK; i++)
if (rch == rnames[i])
return(i);
return(0);
}
get_suit(sch)
int sch;
{
int i;
for (i = 1; i <= MAX_SUIT; i++)
if (sch == *snames[i])
return(i);
return(0);
}
start_new_game()
{
write_socket(dist_socket, "n");
}
join_game(i)
int i;
{
char buf[64];
(void) sprintf(buf, "j%d", i);
write_socket(dist_socket, buf);
}
do_dist()
{
int i;
char buf[64];
if (read_socket(dist_socket, buf) == 0)
dist_died(3);
i = update_table(buf);
show_tables(cur_screen_table);
}
main(argc, argv)
int argc;
char **argv;
{
/* Call init first, in case the client wants to parse arguments */
init(&argc, argv);
if (argc > 2) {
fprintf(stderr, "usage: %s [hostname]\n", *argv);
exit(1);
}
if (argc == 2)
(void) strcpy (host, *++argv);
else
(void) gethostname(host, sizeof(host)); /* host is this machine */
first_game = TRUE;
(void) signal(SIGINT, wimp_out);
for (;;) {
game_over = FALSE;
get_going();
do {
scan();
}
while (!game_over);
}
}